#pragma once

#include "Definitions.h"
#include "SenetBoardDraft.h"
#include "SenetHeuristics.h"
#include "SenetMove.h"
#include "SticksProbability.h"
#include "CommonAlgorithmsDefs.h"
#include "Expectimax.h"
#include <hash_map>

class Star1p
{
public:
	void init(const SenetPlayerExt* owner , int gameStickNum);

	SenetMove scoreStar1p(SenetBoardDraft& board,
		int depth,
		const GameTimer& timer,
		bool checkTime,
		Definitions::PlayerColor myColor,
		int stickNum) throw(Exception);
	
// 	void SetReorder(bool chance, bool minmax)
// 	{
// 		m_IsReorderChanceNodes = chance;
// 		m_IsReorderMinMaxNodes = minmax;
// 	}

	// TODO: remove this
	float m_FinalBoardScore;
	static const bool m_IsReorderChanceNodes = true;
	static const bool m_IsReorderMinMaxNodes = false;
private:
	SenetHeuristics		m_heuristic;
	int					m_gameStickNum;
	int					m_gameTwoThirdStickNum;
	SticksProbability	m_probabilities;
//	stdext::hash_map<int, float> m_prevBoardValues;
	vector<int>			m_OrderedChanceNodes;
	vector<int>			m_UnOrderedChanceNodes;

	void alphabeta(
		Score& res ,
		SenetBoardDraft& board,
		int depth,
		const GameTimer& timer,
		bool checkTime,
		Definitions::PlayerColor currentPlayer,
		int stickNum /* the number of sticks that current player got */,
		NodeType nodeType,
		float alpha,
		float beta,
		bool probe);

	Score chanceSearch(
		SenetBoardDraft& board,
		int depth,
		const GameTimer& timer,
		bool checkTime ,
		Definitions::PlayerColor currentPlayer,
		int stickNum,
		NodeType nodeType,
		NodeType nextTurn,
		float alpha,
		float beta) throw(Exception);

	void star1p(
		Score& res,
		SenetBoardDraft &board,
		int depth,
		const GameTimer& timer,
		bool checkTime, 
		Definitions::PlayerColor nextPlayer,
		NodeType nextTurn,
		float alpha,
		float beta) throw (Exception);

	void star1pImpl(
		Score& res,
		SenetBoardDraft &board,
		int depth,
		const GameTimer& timer,
		bool checkTime, 
		Definitions::PlayerColor nextPlayer,
		NodeType nextTurn,
		float alpha,
		float beta) throw (Exception);

	void reorderMinMaxNodes(SenetBoardDraft& board,
		vector<int>& moves,
		int stickNum,
		Definitions::PlayerColor currentPlayer,
		NodeType type);

	void reorderChanceNodes(vector<int>& outSticksVector);
	// TODO: calculate this in advanced, and save it in the cache
	inline float getProbabilityLeft(int finishedSuccessors /* index i */)
	{
		float total = 0.0f;
		for (int i = finishedSuccessors + 1; i <= m_gameStickNum; ++i)
		{
			total += m_probabilities.getProbability(i);
		}
		return total;
	}
};
